package com.bh.common.utils;

import com.alibaba.fastjson2.JSONArray;
import com.alibaba.fastjson2.JSONObject;
import lombok.extern.slf4j.Slf4j;

import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.math.BigDecimal;
import java.net.URL;
import java.net.URLConnection;
import java.util.HashMap;
import java.util.Map;

/**
 * 地图跑龙套
 *
 * @author shuangluxing@163.com
 * @date 2023/07/01
 */
@Slf4j
public class MapUtils {

    private static final String key = "0bb3f11c0d8613459780ad96775ec38e";

    /**
     * 地址转换为经纬度
     *
     * @param address 地址
     * @param key     高德地图应用key
     * @return 经纬度
     */
    public static Map getLonAndLat(String address) {
        // 返回输入地址address的经纬度信息, 格式是 经度,纬度
        String queryUrl = "http://restapi.amap.com/v3/geocode/geo?key=" + key + "&address=" + address;
        // 高德接口返回的是JSON格式的字符串
        String queryResult = getResponse(queryUrl);
        Map<String, String> map = new HashMap<String, String>();
        JSONObject obj = JSONObject.parseObject(queryResult);
        if ("1".equals(obj.get("status").toString())) {
            JSONArray array = obj.getJSONArray("geocodes");
            if (array != null && array.size() > 0) {
                JSONObject jobJSON = array.getJSONObject(0);
                String location = jobJSON.get("location").toString();
                System.out.println("经纬度：" + location);
                String[] lonAndLat = location.split(",");
                if (lonAndLat.length == 2) {
                    map.put("lng", lonAndLat[0]);
                    map.put("lat", lonAndLat[1]);
                }
                System.out.println(map);
                return map;
            }
        } else {
            log.info("地址转换经纬度失败，错误码：" + obj.get("infocode"));
        }
        return null;
    }


    /**
     * 地址转换为经纬度
     * @param address
     * @return
     */
    public static String getLonAndLatString(String address) {
        Map<String, String> map = getLonAndLat(address);
        if (map != null && map.size() >0) {
            return map.get("lng") + "," + map.get("lat");
        }
        return null;
    }

    /**
     * 将经纬度getLng， getLat 通过getAMapByLngAndLat方法转换地址
     *
     * @return 地址名称
     */
    public static JSONObject getAMapByLngAndLat(String ltl) {
        String[] ltls = ltl.split(",");
        String getLat = ltls[0], getLng = ltls[1];
        String url;
        try {
            url = "http://restapi.amap.com/v3/geocode/regeo?output=JSON&location=" + getLng + "," + getLat + "&key=" + key + "&radius=0&extensions=base";
            // 高德接品返回的是JSON格式的字符串
            String queryResult = getResponse(url);
            // 将获取结果转为json数据
            JSONObject obj = JSONObject.parseObject(queryResult);
            System.out.println("obj为：" + obj);
            if ("1".equals(obj.get("status").toString())) {
                // 如果没有返回-1
                JSONObject regeocode = obj.getJSONObject("regeocode");
                if (regeocode.size() > 0) {
                    // 在regeocode中拿到 formatted_address 具体位置
                    return (JSONObject) regeocode.get("addressComponent");
                } else {
                    throw new RuntimeException("未找到相匹配的地址！");
                }
            } else {
                throw new RuntimeException("请求错误！");
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
        return null;
    }


    /**
     * 将经纬度getLng， getLat 通过getAMapByLngAndLat方法转换地址
     *
     * @return 地址名称
     */
    public static Long getAdcode(String ltl) {
        JSONObject addressComponent = MapUtils.getAMapByLngAndLat(ltl);
        if (addressComponent == null) {
            String[] ltls = ltl.split(",");
            addressComponent = MapUtils.getAMapByLngAndLat(ltls[1] + "," + ltls[0]);
        }
        assert addressComponent != null;
        if (addressComponent.get("adcode") != null) {
            return Long.parseLong(addressComponent.get("adcode").toString());
        }
        return null;
    }

    /**
     * 根据两个定位点的经纬度算出两点间的距离 (单位为： km)
     *
     * @param startLonLat 起始经纬度
     * @param endLonLat   结束经纬度（目标经纬度）
     * @return 两个定位点之间的距离
     */
    private static long getDistance(String startLonLat, String endLonLat) {
        // 返回起始地startAddr与目的地endAddr之间的距离，单位：米
        long result;
        String queryUrl = "http://restapi.amap.com/v3/distance?key=" + key + "&origins=" + startLonLat + "&destination=" + endLonLat;
        String queryResult = getResponse(queryUrl);
        JSONObject obj = JSONObject.parseObject(queryResult);
        JSONArray ja = obj.getJSONArray("results");
        JSONObject jobO = JSONObject.parseObject(ja.getString(0));
        result = Long.parseLong(jobO.get("distance").toString());
        System.out.println("距离：" + result);
        return result;
    }

    public static BigDecimal distanceCalculationSite(String start, String end) {
        //高德地图KEY
        String url = "https://restapi.amap.com/v3/direction/driving?origin=" + start + "&destination=" + end + "&output=json" + "&key=" + key;
        //发型不能乱,如果参数顺序有错误，可能会得到20000的错误，参数错误
        try {
            String queryResult = getResponse(url);
            JSONObject obj = JSONObject.parseObject(queryResult);
            if (obj != null) {
                JSONObject route = (JSONObject) obj.get("route");
                JSONArray paths = (JSONArray) route.get("paths");
                JSONObject path0 = (JSONObject) paths.get(0);
                if (path0.get("distance") != null) {
                    // 装换为公里
                    return BigDecimal.valueOf((Integer.parseInt((String) path0.get("distance"))) / 1000);
                }

            }
        } catch (Exception e) {
            log.info("{高德地图获取两点驾驶距离}------------>" + e);
            e.printStackTrace();
        }
        return BigDecimal.ZERO;
    }

    /**
     * 地址转换为经纬度
     * @param address
     * @return
     */
    public static JSONObject getPOICode(String address) {
        String queryUrl = "https://restapi.amap.com/v3/place/text?key=" + key + "&keywords=" + address + "&offset=5&page=1&extensions=all";
        String queryResult = getResponse(queryUrl);
        JSONObject obj = JSONObject.parseObject(queryResult);
        if (obj != null && obj.get("count") != null && Integer.parseInt(obj.get("count").toString()) > 0) {
            JSONArray array = (JSONArray) obj.get("pois");
            if (array.size() > 0) {
                return (JSONObject) array.get(0);
            }
        }
        return null;
    }

    public static void main(String[] args) {
        System.out.println(getPOICode("红河州建水县"));
    }

    /**
     * 发送请求
     *
     * @param serverUrl 请求地址
     */
    private static String getResponse(String serverUrl) {
        // 用JAVA发起http请求，并返回json格式的结果
        StringBuilder result = new StringBuilder();
        try {
            URL url = new URL(serverUrl);
            URLConnection conn = url.openConnection();
            BufferedReader in = new BufferedReader(new InputStreamReader(conn.getInputStream()));
            String line;
            while ((line = in.readLine()) != null) {
                result.append(line);
            }
            in.close();
        } catch (Exception e) {
            e.printStackTrace();
        }
        return result.toString();
    }
}


